package com.jhf.youke.product.domain.service;

import com.jhf.youke.product.domain.converter.ProductPropertyConverter;
import com.jhf.youke.product.domain.gateway.*;
import com.jhf.youke.product.domain.model.Do.ProductPropertyDo;
import com.jhf.youke.product.domain.model.dto.*;
import com.jhf.youke.product.domain.model.po.ProductPropertyListPo;
import com.jhf.youke.product.domain.model.po.ProductPropertyPo;
import com.jhf.youke.product.domain.model.vo.ProductPropertyVo;
import com.jhf.youke.core.ddd.AbstractDomainService;
import com.jhf.youke.core.entity.PageQuery;
import com.jhf.youke.core.entity.Pagination;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;


/**
 * @author RHJ
 */
@Service
public class ProductPropertyService extends AbstractDomainService<ProductPropertyRepository, ProductPropertyDo, ProductPropertyVo> {


    @Resource
    ProductPropertyConverter productPropertyConverter;

    @Resource
    ProductPropertyListRepository productPropertyListRepository;


    @Override
    public boolean update(ProductPropertyDo entity) {
        ProductPropertyPo productPropertyPo = productPropertyConverter.do2Po(entity);
        productPropertyPo.preUpdate();
        return repository.update(productPropertyPo);
    }

    @Override
    public boolean updateBatch(List<ProductPropertyDo> doList) {
        List<ProductPropertyPo> poList = productPropertyConverter.do2PoList(doList);
        return repository.updateBatch(poList);
    }

    @Override
    public boolean delete(ProductPropertyDo entity) {
        ProductPropertyPo productPropertyPo = productPropertyConverter.do2Po(entity);
        return repository.delete(productPropertyPo);
    }

    @Override
    public boolean deleteBatch(List<Long> idList) {
        return repository.deleteBatch(idList);
    }

    @Override
    public boolean insert(ProductPropertyDo entity) {
        // 主表前置数据要创建ID
        entity.setParentId();
        ProductPropertyPo productPropertyPo = productPropertyConverter.do2Po(entity);
        productPropertyPo.preInsert();
        productPropertyPo.getProductPropertyListPos().forEach(
                productPropertyListPo -> productPropertyListPo.preInsert());
        productPropertyListRepository.insertBatch(productPropertyPo.getProductPropertyListPos());

        return repository.insert(productPropertyPo);
    }

    @Override
    public boolean insertBatch(List<ProductPropertyDo> doList) {
        List<ProductPropertyPo> poList = productPropertyConverter.do2PoList(doList);
        poList = ProductPropertyPo.getInsertListId(poList);
        return repository.insertBatch(poList);
    }

    @Override
    public Optional<ProductPropertyVo> findById(Long id) {
        Optional<ProductPropertyPo> productPropertyPo =  repository.findById(id);
        ProductPropertyVo productPropertyVo = productPropertyConverter.po2Vo(productPropertyPo.orElse(new ProductPropertyPo()));
        return Optional.ofNullable(productPropertyVo);

    }

    @Override
    public boolean remove(Long id) {
        return repository.remove(id);
    }

    @Override
    public boolean removeBatch(List<Long> idList) {
        return repository.removeBatch(idList);
    }

    @Override
    public List<ProductPropertyVo> findAllMatching(ProductPropertyDo entity) {
        ProductPropertyPo productPropertyPo = productPropertyConverter.do2Po(entity);
        List<ProductPropertyPo> productPropertyPoList =  repository.findAllMatching(productPropertyPo);
        return productPropertyConverter.po2VoList(productPropertyPoList);
    }


    @Override
    public Pagination<ProductPropertyVo> selectPage(ProductPropertyDo entity){
        ProductPropertyPo productPropertyPo = productPropertyConverter.do2Po(entity);
        PageQuery<ProductPropertyPo> pageQuery = new PageQuery<>(productPropertyPo,entity.getCurrentPage(), entity.getPageSize(), entity.getQuerySort());
        Pagination<ProductPropertyPo> pagination = repository.selectPage(pageQuery);
        return new Pagination<ProductPropertyVo>(pagination.getPageNum(),pagination.getPageSize(),pagination.getTotalSize(),
                productPropertyConverter.po2VoList(pagination.getList()));
    }


    @Transactional(rollbackFor = Exception.class)
    public Map<String, ProductPropertyListPo> addProductProperty(ProductReleaseEditDto dto){
        int moreSpec = 2;
        Map<String, ProductPropertyListPo> map = new HashMap<>(16);
        List<ProductPropertyPo> poList = new ArrayList<>();
        List<ProductPropertyListPo> propertyListPos = new ArrayList<>();
        //是多规格商品
        if(dto.getSpecType() == moreSpec) {
            for (GoodsSpecDto item:dto.getMultipleSpecList()) {
                ProductPropertyPo productPropertyPo = new ProductPropertyPo();
                productPropertyPo.setName(item.getName());
                productPropertyPo.setCompanyId(dto.getCompanyId());
                productPropertyPo.setProductReleaseId(dto.getId());
                productPropertyPo.preInsert();
                poList.add(productPropertyPo);


                for(GoodsSpecItemDto specItem:item.getItemList()){
                    ProductPropertyListPo productPropertyListPo = new ProductPropertyListPo();
                    productPropertyListPo.setName(specItem.getName());
                    productPropertyListPo.setProductPropertyId(productPropertyPo.getId());
                    productPropertyListPo.preInsert();
                    propertyListPos.add(productPropertyListPo);
                    map.put(productPropertyListPo.getName(), productPropertyListPo);
                }
            }
        }

        if(!poList.isEmpty()){
            repository.insertBatch(poList);
            if(!propertyListPos.isEmpty()){
                productPropertyListRepository.insertBatch(propertyListPos);
            }
        }

        return map;
    }

    public Map<String, ProductPropertyListPo> updateProductProperty(ProductReleaseEditDto dto){
        Map<String, ProductPropertyListPo> map = new HashMap<>(32);
        //是多规格商品
        int moreSpec = 2;
        if(dto.getSpecType() == moreSpec) {
            ProductPropertyPo param = new ProductPropertyPo();
            param.setProductReleaseId(dto.getId());
            List<ProductPropertyPo> propertyList =  repository.findAllMatching(param);

            List<ProductPropertyListPo> propertyListPos = new ArrayList<>();

            //需要删除的规格
            List<Long> propertyDelIds = new ArrayList<>();
            //需要删除的规格选项
            List<Long> propertyListDelIds = new ArrayList<>();

            for(ProductPropertyPo item:propertyList){
                Boolean isDel = true;
                for (GoodsSpecDto goodsSpec:dto.getMultipleSpecList()) {
                    if(goodsSpec.getId().equals(item.getId())){
                        isDel = false;
                        break;
                    }
                }
                if(isDel){
                    propertyDelIds.add(item.getId());
                }

                ProductPropertyListPo itemParam = new ProductPropertyListPo();
                itemParam.setProductPropertyId(item.getId());
                List<ProductPropertyListPo> list = productPropertyListRepository.findAllMatching(itemParam);
                if(list.size() > 0) {
                    propertyListPos.addAll(list);
                }
            }

            for (GoodsSpecDto item:dto.getMultipleSpecList()) {
                ProductPropertyPo productPropertyPo = new ProductPropertyPo();
                productPropertyPo.setName(item.getName());
                if(item.getId() == null) {
                    //新增
                    productPropertyPo.setCompanyId(dto.getCompanyId());
                    productPropertyPo.setProductReleaseId(dto.getId());
                    productPropertyPo.preInsert();
                    repository.insert(productPropertyPo);
                }else {
                    //修改
                    productPropertyPo.setId(item.getId());
                    productPropertyPo.preUpdate();
                    repository.update(productPropertyPo);
                }

                for(GoodsSpecItemDto specItem:item.getItemList()){
                    ProductPropertyListPo productPropertyListPo = new ProductPropertyListPo();
                    productPropertyListPo.setName(specItem.getName());
                    if(specItem.getId() == null){
                        //添加
                        productPropertyListPo.setProductPropertyId(productPropertyPo.getId());
                        productPropertyListPo.preInsert();
                        productPropertyListRepository.insert(productPropertyListPo);
                    }else {
                        //修改
                        productPropertyListPo.setId(specItem.getId());
                        productPropertyListPo.preUpdate();
                        productPropertyListRepository.update(productPropertyListPo);
                    }
                    map.put(productPropertyListPo.getName(), productPropertyListPo);
                }
            }

            for(ProductPropertyListPo item:propertyListPos){
                ProductPropertyListPo poMap = map.get(item.getName());
                if(poMap == null){
                    propertyListDelIds.add(item.getId());
                }
            }
            if(propertyDelIds.size() > 0){
                repository.deleteBatch(propertyDelIds);
            }
            if(propertyListDelIds.size() > 0){
                productPropertyListRepository.deleteBatch(propertyListDelIds);
            }
        }
        return map;
    }
}

